package com.daka.tools;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES对称加密算法
 *
 * @author
 */
public class AesUtil {
	// 密钥算法
	private static final String KEY_ALGORITHM = "AES";

	// 加解密算法/工作模式/填充方式
	private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

	private static final int KEYSIZE = 128;

	/**
	 * 生成密钥
	 *
	 * @return the string
	 * @throws Exception the exception
	 */
	public static String initAesKey() throws Exception {
		try {
			KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM); // 实例化密钥生成器
			kg.init(KEYSIZE); // 初始化密钥生成器:AES要求密钥长度为128,192,256位
			SecretKey secretKey = kg.generateKey(); // 生成密钥

			byte[] keyb = secretKey.getEncoded();
			String key = byteToHexString(keyb); // 二进制转换成十六进制

			System.out.println(key);

			return key;
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * 加密
	 *
	 * @param data the data
	 * @param key  the key
	 * @return String result 加密后的数据
	 * @throws Exception the exception
	 */
	public static String encrypt(String data, String key) throws Exception {
		byte[] resultb = encrypt(data, hexStringToByte(key)); // 加密后数据
		return byteToHexString(resultb); // 加密后数据
	}

	/**
	 * 加密
	 *
	 * @param data the data
	 * @param keyb the keyb
	 * @return byte[] encryptData 加密后的数据
	 * @throws Exception the exception
	 */
	public static byte[] encrypt(String data, byte[] keyb) throws Exception {

		SecretKeySpec sKeySpec = new SecretKeySpec(keyb, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 实例化Cipher对象，它用于完成实际的加密操作
		cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); // 初始化Cipher对象，设置为加密模式
		return cipher.doFinal(data.getBytes("utf8")); // 加密后数据

	}

	/**
	 * 解密
	 *
	 * @param data the data
	 * @param key  the key
	 * @return String result 解密后的数据
	 * @throws Exception the exception
	 */
	public static String decrypt(String data, String key) throws Exception {

		byte[] datab = hexStringToByte(data);
		byte[] keyb = hexStringToByte(key);
		return decrypt(datab, keyb); // 解密后数据

	}

	/**
	 * 解密
	 *
	 * @param datab the datab
	 * @param keyb  the keyb
	 * @return String result 解密后的数据
	 * @throws Exception the exception
	 */
	public static String decrypt(byte[] datab, byte[] keyb) throws Exception {

		SecretKeySpec sKeySpec = new SecretKeySpec(keyb, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 实例化Cipher对象，它用于完成实际的加密操作
		cipher.init(Cipher.DECRYPT_MODE, sKeySpec); // 初始化Cipher对象，设置为加密模式
		byte[] resultb = cipher.doFinal(datab); // 解密
		return new String(resultb, "UTF-8"); // 解密后数据

	}

	/**
	 * 二进制byte[]转十六进制string
	 *
	 * @param bytes the bytes
	 * @return the string
	 */
	public static String byteToHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder();
		for (byte aByte : bytes) {
			String strHex = Integer.toHexString(aByte);
			if (strHex.length() > 3) {
				sb.append(strHex.substring(6));
			} else {
				if (strHex.length() < 2) {
					sb.append("0").append(strHex);
				} else {
					sb.append(strHex);
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 十六进制string转二进制byte[]
	 *
	 * @param s the s
	 * @return the byte [ ]
	 */
	public static byte[] hexStringToByte(String s) {
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(
						s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				System.out.println("十六进制转byte发生错误！！！");
				e.printStackTrace();
			}
		}
		return baKeyword;
	}

	/**
	 * The entry point of application.
	 *
	 * @param args the input arguments
	 * @throws Exception the exception
	 */
	public static void main(String[] args) throws Exception {
		try {

			// 生成密钥
			//String key2 = initAesKey();
			// 测试用
			String key = "17e4f4e492f67bd3d845a0aecaf2089f";

			// 加密原串
			String source = "439ddd43a14c3de1f026惺惺惜惺惺41f62657df9e打发士大夫说0b40273f04fd98619c17469627aea3088708dd2b1e6500ccf42baacc03848518906e7";
			System.out.println("原文： ");
			System.out.println(source);

			// AES加密
			String encryptData = encrypt(source, key);
			System.out.println("加密密文 ： ");
			System.out.println(encryptData);

			// AES解密
			//encryptData = "1e923dc8ad73b1a3a2d65fb227cc9509c83e48385c8c803b2fd927cdfbbc081adeea1cdc931bb4d7e7f5b91efd061462fad68bac7b1dc915de0fe351a118cce89d4f502e158ed62f945db7cd9a76b036414eae7bf89bbc5ecff6d379ebaafeaabc999eee263c05a614ed17fcea5e8c3861a8f155c3d45fc70e2c8810f4c010ca27cdd12318acf4950e97eaef8ca95016b68cbda2f9e389d8eff97e612715b0319ad95191c5c71cfc7a0675e2f714ca36d864c1df54fdb2a9af447f673b606866683715d7e236cf59ace190baf7feb7929c66c16a5b58734580172bdab2e4904f55941ad554751acb73b77c084348e1e86804340914a161d6ba728015ac9e05e0db0cb59440fbb0c22d6d9db643bf749401f85be50c05f92f94bc94e3883bb6c0b77c6ad79faf57dc6934c59603df690b224db80b17f69e10a2a1d3533914d31de4d02be65d7fe9df4ae3e9b7b779a6a265179405ebfdc19eb2aff8ee018d9f0d9cc04b358d18489743b0b5475557ad3f5018ff0bbdd0d9018c18a6502cd6e69ed71d81fb2264ee8b8229f4ac4bf4e680857932e86938e527856a8b45d0bd5af4176f16e4856a85d97570e29f0766de3cc4f4cdd68080e43037289b8093e4352645c15ffbf9361b4cbd8bdf87a7471e086ed39d171d215e356ea3d275808bdf8354636778456df763e8b226d5bcf2a3381426c064c755d1ee587b6ee443ee7a89b41cf242927d1fb27722f015d47ffabeff19dcfa9ab7d9e48c19c927617cfc314f486da494f6eb7fe76390eefdb9b3ef113095a5a24a16416af2c0f49065c75da687a59032c7d9f7bbff4431e3ac5db00900baf140a8415685469d4e603144e7";
			String decryptData = decrypt(encryptData, key);
			System.out.println("解密原文: ");
			System.out.println(decryptData);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

	}

}
